﻿using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.AspNetCore.Identity;

namespace Devonline.Identity;

/// <summary>
/// 角色, 字符串类型的默认实现
/// </summary>
[Table("role"), DisplayName("角色")]
public class Role : Role<string>, IIdentity, IEntitySet, IEntitySetWithCreate, IEntitySetWithCreateAndUpdate
{
    /// <summary>
    /// 通用附件集合, NotMapped Attachments 用于记录实体对象上上传的附件
    /// </summary>
    [NotMapped]
    public virtual ICollection<Attachment> Attachments { get; set; }
}

/// <summary>
/// 角色, 字符串类型的默认实现
/// </summary>
[Table("role"), DisplayName("角色")]
public class Role<TKey> : IdentityRole<TKey>, IIdentity<TKey>, IEntitySet<TKey>, IEntitySetWithCreate<TKey>, IEntitySetWithCreateAndUpdate<TKey> where TKey : IEquatable<TKey>, IConvertible
{
    public Role()
    {
        Id = KeyGenerator.GetKey<TKey>();
        RowVersion = Id;
    }

    /// <summary>
    /// 数据主键
    /// </summary>
    [Column("id"), DisplayName("编号"), DatabaseGenerated(DatabaseGeneratedOption.None), Key, MaxLength(36), Excel]
    public override TKey Id { get; set; }
    /// <summary>
    /// 名称
    /// </summary>
    [ProtectedPersonalData]
    [Column("name"), Required, Unique, MaxLength(256), DisplayName("名称"), Excel]
    public override string Name { get; set; }
    /// <summary>
    /// 昵称
    /// </summary>
    [Column("alias"), MaxLength(36), DisplayName("昵称"), Excel]
    public virtual string Alias { get; set; }
    /// <summary>
    /// 头像
    /// </summary>
    [Column("image"), MaxLength(128), DisplayName("头像"), BusinessType(IsAttachment = true), Excel]
    public virtual string Image { get; set; }
    /// <summary>
    /// 身份类型
    /// </summary>
    [Column("type", TypeName = "VARCHAR(16)"), DisplayName("身份类型"), DefaultValue(AuthorizeType.Internal), Excel]
    public virtual AuthorizeType Type { get; set; }
    /// <summary>
    /// 行版本号
    /// </summary>
    [Column("row_version"), DisplayName("行版本号"), ConcurrencyCheck]
    public virtual TKey RowVersion { get; set; }
    /// <summary>
    /// 数据状态
    /// </summary>
    [Column("state", TypeName = "VARCHAR(16)"), DisplayName("数据状态"), DefaultValue(DataState.Available), Excel]
    public virtual DataState State { get; set; }
    /// <summary>
    /// 创建时间
    /// </summary>
    [Column("created_on"), DisplayName("创建时间"), Excel]
    public virtual DateTime? CreatedOn { get; set; }
    /// <summary>
    /// 创建人
    /// </summary>
    [Column("created_by"), DisplayName("创建人"), MaxLength(36), Excel]
    public virtual string CreatedBy { get; set; }
    /// <summary>
    /// 更新时间
    /// </summary>
    [Column("updated_on"), DisplayName("更新时间"), Excel]
    public virtual DateTime? UpdatedOn { get; set; }
    /// <summary>
    /// 更新人
    /// </summary>
    [Column("updated_by"), DisplayName("更新人"), MaxLength(36), Excel]
    public virtual string UpdatedBy { get; set; }
    /// <summary>
    /// 备注说明
    /// </summary>
    [Column("description"), DisplayName("备注说明"), MaxLength(256), Excel]
    public virtual string Description { get; set; }
    /// <summary>
    /// Gets or sets the normalized name for this role
    /// </summary>
    [Column("normalized_name"), MaxLength(64), DisplayName("归一角色名"), Excel]
    public override string NormalizedName { get; set; }
    /// <summary>
    /// A random value that should change whenever a role is persisted to the store
    /// </summary>
    [Column("concurrency_stamp"), DisplayName("并发特征"), MaxLength(36)]
    public override string ConcurrencyStamp { get; set; }

    /// <summary>
    /// 创建方法
    /// </summary>
    public virtual void Create(string createdBy = null, DateTimeKind kind = DateTimeKind.Utc)
    {
        Id ??= KeyGenerator.GetKey<TKey>();
        RowVersion = Id;
        CreatedOn ??= DateTime.SpecifyKind(DateTime.Now, kind);
        CreatedBy ??= createdBy ?? AppSettings.USER_SYSTEM;
        ConcurrencyStamp ??= Id.ToString();
    }

    /// <summary>
    /// 更新方法
    /// </summary>
    public virtual void Update(string updatedBy = null, DateTimeKind kind = DateTimeKind.Utc)
    {
        RowVersion = KeyGenerator.GetKey<TKey>();
        UpdatedOn ??= DateTime.SpecifyKind(DateTime.Now, kind);
        UpdatedBy ??= updatedBy ?? AppSettings.USER_SYSTEM;
        ConcurrencyStamp ??= RowVersion.ToString();
    }
}